package ru.alexo.whiskey;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import ru.alexo.whiskey.events.TrackEvent;

/**
 * Encapsulates the MIDI track.
 * 
 * @author Exaybachay
 */
public class MidiTrack {

    private static final int FOOTER_SIZE = 4;

    private static final int TRACK_FOOTER = (int) 0xFF2F00;

    private static final String TRACK_HEADER = "MTrk";

    private final List<TrackEvent> events = new ArrayList<TrackEvent>();

    MidiTrack() {
    }

    /**
     * Adds new event to the track.
     * 
     * @param event
     */
    public void addEvent(TrackEvent event) {
	events.add(event);
    }

    /**
     * Serializes the track information as an array of bytes.
     * 
     * @return byte array of the track information
     * @throws IOException
     */
    public byte[] getTrackBytes() throws IOException {
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	DataOutputStream dos = new DataOutputStream(baos);

	try {
	    dos.writeBytes(TRACK_HEADER);

	    ByteArrayOutputStream trackStream = new ByteArrayOutputStream();
	    int offset = 0;
	    for (TrackEvent trackEvent : events) {
		offset = trackEvent.serializeToStream(trackStream, offset);
	    }
	    dos.writeInt(trackStream.size() + FOOTER_SIZE);
	    dos.write(trackStream.toByteArray());
	    trackStream.close();

	    dos.writeInt(TRACK_FOOTER);
	    dos.flush();

	    return baos.toByteArray();
	} finally {
	    dos.close();
	}
    }

}
